<?php
    // Setup PHP
    error_reporting(E_ALL | E_STRICT);
    set_error_handler('handleError');
    
    require('./config.php');
    require('./lang.en.php');
    date_default_timezone_set(config('TIMEZONE'));

    // Constants
    // For HtmlPage Class
    define('PUSH_TAB', 1 << 0);
    define('POP_TAB', 1 << 1);
    
    // Classes
    class HtmlPage {
        private $tabs = 0;
        
        public function write($text, $flags = 0) {
            // Pop tab
            if( ($flags&POP_TAB) != 0 ) {
                if($this->tabs == 0)
                    throw new Exception('Tried to pop non existent tab.');
                $this->tabs--;
            }
            
            // Echo text
            for($i=0;$i<$this->tabs;$i++)
                echo "\t";
            echo $text;
            echo "\n";
            
            // Push tab
            if( ($flags&PUSH_TAB) != 0 )
                $this->tabs++;
        }
        
        public function writeHeader($pagename, $flags = 0) {                
            $this->write('<!DOCTYPE html>');
            $this->write('<html>', PUSH_TAB);
            $this->write('<head>', PUSH_TAB);
            $this->write('<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />');
            $this->write('<link rel="stylesheet" type="text/css" href="style.css" />');
            $this->write('<title>'.lang('MAIN_TITLE').' - '.$pagename.'</title>');
            $this->write('</head>', POP_TAB);
            $this->write('<body>', PUSH_TAB);
        }
        
        public function writeFooter() {
            $this->write('</body>', POP_TAB);
            $this->write('</html>', POP_TAB);
        }
        
        public function writeMenu($page, $user) {
            $this->write('<div class="menu">', PUSH_TAB);
            $this->write('<ul>', PUSH_TAB);

            if( $user['group'] > 1 ) {
                if($page == 'HOME')
                    $this->write('<li>'.lang('HOME_PAGENAME').'</li>');
                else
                    $this->write('<li><a href="index.php">'.lang('HOME_PAGENAME').'</a></li>');
                if($page == 'BLOCKS')
                    $this->write('<li>'.lang('BLOCKS_PAGENAME').'</li>');
                else
                    $this->write('<li><a href="blocks.php">'.lang('BLOCKS_PAGENAME').'</a></li>');
                if($page == 'USERS')
                    $this->write('<li>'.lang('USERS_PAGENAME').'</li>');
                else
                    $this->write('<li><a href="users.php">'.lang('USERS_PAGENAME').'</a></li>');
                /*if($page == 'SETTINGS')
                    $this->write('<li>'.lang('SETTINGS_PAGENAME').'</li>');
                else
                    $this->write('<li><a href="settings.php">'.lang('SETTINGS_PAGENAME').'</a></li>');*/
            }

            $this->write('<li>'.lang('LOGGED_IN_AS').htmlEscape($user['name']).'</li>');
            
            $this->write('<li>', PUSH_TAB);
            $this->write('<form action="dologout.php" method="post">', PUSH_TAB);
            $this->write(getCsrfGuard());
            $this->write('<input type="submit" value="'.lang('LOGOUT').'" />');
            $this->write('</form>', POP_TAB);
            $this->write('</li>', POP_TAB);

            $this->write('</ul>', POP_TAB);
            $this->write('</div>', POP_TAB);
        }
        
        public function writeTitle() {
            $this->write('<h1><a href="index.php">'.lang('MAIN_TITLE').'</a></h1>');
        }
    }
    
    class Database {
        function __construct() {
            $this->db = @mysqli_connect(
                config('DB_HOST'), 
                config('DB_USER'),
                config('DB_PASSWORD'),
                config('DB_NAME'),
                config('DB_PORT'));
            if(!$this->db)
                throw new Exception('Couldn\'t connect to database.');
        }
        
        function query($q) {
            $r = mysqli_query($this->db, $q);
            if(!$r)
                throw new Exception('Query failed :'.mysqli_error($this->db));
            return $r;
        }
        
        function insertId() {
            return mysqli_insert_id($this->db);
        }
        
        function escape($str) {
            if(is_null($str))
                return 'NULL';
            else
                return '\''.mysqli_real_escape_string($this->db, $str).'\'';
        }

        function intval($i) {
            if(is_null($i))
                return 'NULL';
            else
                return intval($i);
        }

        function __destruct() {
            mysqli_close($this->db);
        }
    }
    
    // Functions
    function handleError($errno, $errstr, $errfile, $errline, array $errcontext) {
        // error was suppressed with the @-operator
        if (0 === error_reporting()) {
            return false;
        }

        throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
    }
    
    function lang($textid) {
        $l = langArray();
        return $l[$textid];
    }

    function checkCsrfGuard() {
        if(!isset($_POST['csrf_guard']))
            throw new Exception('Bad CSRF guard');
        if(!isset($_COOKIE['password']))
            throw new Exception('Bad CSRF guard');
        if($_POST['csrf_guard'] != $_COOKIE['password'])
            throw new Exception('Bad CSRF guard');
    }
    
    function getCsrfGuard() {
        return '<input type="hidden" name="csrf_guard" value="'.
            htmlEscape($_COOKIE['password']).'" />';
    }
    
    function htmlEscape($str) {
        return htmlentities($str, ENT_COMPAT, 'utf-8');
    }
    
    function message($msg, $link, $linkmsg) {
        redirect('message.php'.
            '?msg='.urlencode($msg).
            '&link='.urlencode($link).
            '&linkmsg='.urlencode($linkmsg));
    }
    
    function redirect($link) {
        header('Location: '.config('BASE_URL').'/'.$link);
    }
        
    function getUser($db) {
        // Check that the cookie is set correctly
        if(!isset($_COOKIE['user_id']) || !isset($_COOKIE['password']) )
            return array('name' => 'Guest', 'group' => 0, 'id' => -1);
        
        // Get the password
        $result = $db->query('SELECT password, name, group_id FROM '.
            config('DB_PREFIX').'users WHERE id='.
            intval($_COOKIE['user_id']));
        if(mysqli_num_rows($result) == 0)
            return array('name' => 'Guest', 'group' => 0, 'id' => -1);
        $result = mysqli_fetch_assoc($result);
        $password = $result['password'];
        $name = $result['name'];
        $group = $result['group_id'];
        
        // Check that the password is correct
        if($_COOKIE['password'] != $password)
            return array('name' => 'Guest', 'group' => 0, 'id' => -1);
        
        return array('name' => $name, 
            'group' => $group, 
            'id' => intval($_COOKIE['user_id']));
    }
    
    function getUserFromPost($db) {
        // Check that the post data is set correctly
        if(!isset($_POST['username']) || !isset($_POST['password']))
            return array('name' => 'Guest', 'group' => 0, 'id' => -1);
            
        // Get the password
        $result = $db->query('SELECT id, name, password, salt, group_id FROM '.
            config('DB_PREFIX').'users WHERE name='.
            $db->escape($_POST['username']));
        if(mysqli_num_rows($result) == 0)
            return array('name' => 'Guest', 'group' => 0, 'id' => -1);
        $result = mysqli_fetch_assoc($result);
        
        // Check that the password is correct
        if($result['password'] != sha1($result['salt'].$_POST['password']))
            return array('name' => 'Guest', 'group' => 0, 'id' => -1);

        return array('name' => $result['name'], 
            'group' => $result['group_id'], 
            'id' => intval($result['id']));
    }
    
    function generateSalt() {
        $characterList = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        $i = 0;
        $salt = '';
        do {
            $salt .= $characterList{mt_rand(0,strlen($characterList)-1)};
            $i++;
        } while ($i <= 40);
        return $salt;
    }
    
    function getSetting($db, $name) {
        $result = $db->query('SELECT value FROM '.config('DB_PREFIX').'misc '.
            'WHERE name='.$db->escape($name));
        if(mysqli_num_rows($result) != 1)
            throw new Exception('Setting not found');
        $row = mysqli_fetch_assoc($result);
        return $row['value'];
    }        
?>